package com.qingzhu.component.lock.starter.config;

import com.qingzhu.component.lock.common.cache.LockCache;
import com.qingzhu.component.lock.common.cache.expire.strategy.CacheOutStrategy;
import com.qingzhu.component.lock.common.config.LockProperties;
import com.qingzhu.component.lock.common.constant.AutoConfig;
import com.qingzhu.component.lock.common.generator.LockGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;

/**
 * lock组件的自动装配类，注册所需要的内部bean
 * @author xiangjz
 * @version 1.0
 * @date 2020/9/4 9:32
 */
@ConditionalOnProperty(prefix = AutoConfig.CONFIG_PREFIX, name = "enable", havingValue = "true")
@EnableConfigurationProperties({LockProperties.class})
@Slf4j
public class LockComponentAutoConfiguration implements ApplicationContextAware, InitializingBean {

    private ApplicationContext applicationContext;

    private final LockProperties lockProperties;

    public LockComponentAutoConfiguration(LockProperties lockProperties) {
        this.lockProperties = lockProperties;
    }

    private String getBeanName(String lockType, Class<?> clazz) {
        return lockType + clazz.getSimpleName();
    }

    @Bean
    public LockGenerator lockGenerator() {
        String lockType = lockProperties.getType();
        // 将对应的bean注册即可
        return this.applicationContext.getBean(getBeanName(lockType, LockGenerator.class), LockGenerator.class);
    }

    @Bean
    public LockCache lockCache() {
        String lockType = lockProperties.getType();
        // 将对应的bean注册即可
        return this.applicationContext.getBean(getBeanName(lockType, LockCache.class), LockCache.class);
    }

    @Bean
    public CacheOutStrategy cacheOutStrategy() {
        String strategyForCapacity = lockProperties.getStrategyForCapacity();
        // 将对应的bean注册即可
        return this.applicationContext.getBean(getBeanName(strategyForCapacity, CacheOutStrategy.class), CacheOutStrategy.class);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("{} init success, your application runs with lock type '{}'", AutoConfig.COMPONENT_LOCK_LOG_PREFIX, lockProperties.getType());
    }
}
